#include <string.h>
#include <memory>
#include <thread>
#include <functional>
#include <stdio.h>
#include <iostream>
#include <unistd.h>

/*
 * 线程局部存储
 */

/*
 * 线程 之间共享 全局变量，对 全局变量 进行操作时，会影响其他线程
 * 
 * 多个线程使用同一个入口函数，并打印其中临时变量的地址
 */

using namespace std;

int g_val = 100;

string toHex(pthread_t t)
{
    char id[64];
    snprintf(id, sizeof(id), "0x%x", t);
    return id;
}

void *threadRun(void *arg)
{
    cout << "thread: " << toHex(pthread_self()) << " g_val: " << ++g_val << " &g_val: " << &g_val << endl;
    return (void*)0;
}

int main()
{
    pthread_t t[3];
    for(int i = 0; i < 3; i++)
    {
        pthread_create(t + i, nullptr, threadRun, nullptr);
        sleep(1);
    }

    for(int i = 0; i < 3; i++)
        pthread_join(t[i], nullptr);
    return 0;
}

#if 0
/* 在三个线程的影响下，g_val 最终变成了 103 */
thread: 0x9f6b4700 g_val: 101 &g_val: 0x558fba2ba010
thread: 0x9eeb3700 g_val: 102 &g_val: 0x558fba2ba010
thread: 0x9e6b2700 g_val: 103 &g_val: 0x558fba2ba010

/* 如何让全局变量私有化呢？即每个线程看到的全局变量不同 */

可以给全局变量加 __thread 修饰，修饰之后，全局变量不再存储至全局数据区，而且存储至线程的 局部存储区中

__thread int g_val = 100;

结果：修饰之后，每个线程确实看到了不同的 “全局变量”

特点：此时的 “全局变量” 的地址变大了。

“全局变量” 地址变大是因为此时它不再存储在 全局数据区 中，而且存储在线程的 局部存储区 中，
线程的局部存储区位于 共享区，并且 共享区 的地址天然大于 全局数据区


注意： 局部存储区位于共享区中，可以通过 __thread 修饰来改变变量的存储位置

#endif
